package code;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import common.BaseTask;
import common.EnginService;
import common.IHandler;
import common.Message;
import common.NetChannel;
import common.ServerAttributeKey;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.Attribute;

/**
 * 服务器网络层业务接受handler
 * 由此像业务层派发业务
 * @author King
 *
 */
public class ClientChannelHandler extends SimpleChannelInboundHandler<Message> {

	
	private static final Logger log = LoggerFactory.getLogger(ClientChannelHandler.class); 
	
	protected EnginService service;

	public void setEnginService(EnginService service)
	{
		this.service = service;
	}
	
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		super.channelActive(ctx);
		service.getChannelManager().addChannel(ctx.channel());
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		super.exceptionCaught(ctx, cause);
		ctx.close();
	}
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, Message msg)
			throws Exception 
	{
		IHandler handler = service.getHandlerManager().getHandler(msg.getmId(), msg.gethId());
		
		BaseTask task = new BaseTask(msg,handler,service);
		
		try {
			if(service.getThreadService()==null)
			{
				task.execute();
				return;
			}
			service.getThreadService().publishTask(task);
		} catch (Throwable e) {
			log.error("error",e);
//			throw new Exception(e);
		}
	}
	
	@Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (!(evt instanceof IdleStateEvent)) {
            return;
        }
        Channel channel = ctx.channel();
        IdleStateEvent e = (IdleStateEvent) evt;
        //1次写超时就发送心跳包
        if (e.state() == IdleState.WRITER_IDLE) {
        	//发送心跳包
        	Message msg = Message.newMessage();
        	msg.setmId(Message.M_ID);
        	msg.sethId(Message.H_SEND_HEART_BEAT);
        	channel.writeAndFlush(msg);
        }
        //2次读超时就认为断开连接了
        if (e.state() == IdleState.READER_IDLE) {
        	Attribute<NetChannel> attr = channel.attr(ServerAttributeKey.netChannel);
      		NetChannel netChannel = attr.get();
        	if(netChannel!=null)
        	{
        		if(!netChannel.isHeartBeat())
        		{
        			netChannel.setHeartBeat(true);
        			return;
        		}
        	}
        	ctx.close();
//        	断开连接
//        	disconnet(channel);
            System.out.println("not recieve heart beat");
        }
    }
	
	
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception
	{
		super.channelInactive(ctx);
		disconnet(ctx.channel());
	}
	
	private void disconnet(Channel channel) throws Exception
	{
		service.getChannelManager().delChannel(channel);
		Attribute<NetChannel> attr = channel.attr(ServerAttributeKey.netChannel);
		NetChannel netChannel = attr.get();
		if(netChannel==null||netChannel.isKick())
		{
			return;
		}
		//抛出掉线消息给业务线程
		Message msg = Message.newMessage();
		msg.setChannel(attr.get());
		msg.setmId(Message.M_ID);
		msg.sethId(Message.H_DISCONNET);
		IHandler handler = service.getHandlerManager().getHandler(msg.getmId(), msg.gethId());
		BaseTask task = new BaseTask(msg,handler,service);
		try {
			if(service.getThreadService()==null)
			{
				task.execute();
				return;
			}
			service.getThreadService().publishTask(task);
		} catch (Throwable e) {
			log.error("error",e);
		}
	}
}
